from flask import abort, jsonify
from flask import render_template, current_app, g
from flask import request

from info.modules.utils.common import user_login_data

from info import constants, db
from info.models import News, Comment, CommentLike
from info.modules.utils.response_code import RET
from . import news_blu

# 新闻详情
@news_blu.route("/<int:news_id>")
@user_login_data
def news_detail(news_id):
    # 右侧新闻点击排行
    news_list = []
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)

    range_news_list = []
    # 如果news_list是空,返回None,不报错=>news_list is not iterator
    # ???????????????????????????????????????????疑问
    for news in news_list if news_list else None:
        # news 是一个User的对象,即模板对象,自定义函数to_basic_dict()
        range_news_list.append(news.to_basic_dict())


    # 详情页新闻数据展示
    news = None
    try:
        news = News.query.get(news_id)
    except Exception as e:
        abort(404)

    if not news:
        abort(404)

    # 回头验证点击次数怎么是加1此
    news.clicks += 1
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)




    # 根据数据库显示新闻是否被收藏
    is_collected = False
    if g.user:
        collection_news = g.user.collection_news
        if news in collection_news:
            is_collected = True


    # 根据新闻,显示新闻的评论
    comments_bq = []
    try:
        comments_bq = Comment.query.filter(Comment.news_id==news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)

    comments_dict = []
    for comment in comments_bq:
        comments_dict.append(comment.to_dict())



    # 组装数据
    data = {
        # 如果g.user是空, 就将None赋值给user_info
        "user_info": g.user.to_dict() if g.user else None,
        "range_news_list": range_news_list,
        "news": news.to_dict(),
        "is_collected": is_collected,
        "comments": comments_dict
    }
    return render_template("news/detail.html", data=data)


# 收藏新闻
@news_blu.route("/news_collect", methods=["POST"])
@user_login_data
def news_collect():
    # 1. 接收参数
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    json_data = request.json
    news_id = json_data.get("news_id")
    action = json_data.get("action")
    current_app.logger.debug(news_id)

    # 2. 校验函数
    if not news_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ("collect", "cancel_collect"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3. 查询新闻
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="新闻查询错误")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")

    # 4. 操作数据
    if action == "collect":
        user.collection_news.append(news)
    else:
        user.collection_news.remove(news)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="错作失败")

    # 5. 相应体
    return jsonify(errno=RET.OK, errmsg="操作成功")


# 新闻评论,评论评论
@news_blu.route("/news_comment", methods=["POST"])
@user_login_data
def news_comment():
    # 1. 接收数据
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    json_data = request.json
    news_id = json_data.get("news_id")
    comment_msg = json_data.get("comment")
    parent_id = json_data.get("parent_id")

    # 2. 校验数据
    if not all([news_id, comment_msg]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")

    # 3. 查询新闻
    news = News.query.get(news_id)
    if not news:
        return jsonify(RET.NODATA, errmsg="新闻不存在")

    # 4. 存储评论
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news.id
    comment.content = comment_msg
    if parent_id:
        comment.parent_id = parent_id

    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        db.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="操作失败")

    data = {
        "comment": comment.to_dict()
    }
    # 5. 响应结果
    return jsonify(errno=RET.OK, errmsg="OK", data=data)

# 新闻评论点赞
@news_blu.route("/comment_like", methods=["POST"])
@user_login_data
def comment_like():
    # comment_id, news_id, action
    # 1. 获取参数,comment_id, news_id, action 通过评论下方有评论和点赞两个按钮,都在一个div标签中
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="点赞需要先登录")

    json_data = request.json
    comment_id = json_data.get("comment_id")
    news_id = json_data.get("news_id")
    action = json_data.get("action")

    # 2. 校验参数
    if not all([comment_id, news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")

    if action not in ["add", "remove"]:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="数据查询失败")

    if not comment:
        return jsonify(errno=RET.PARAMERR, errmsg="该评论不存在")

    # 3. 查询赞,添加,删除赞
    try:
        comment_like_query = CommentLike.query.filter(CommentLike.user_id == user.id,CommentLike.comment_id == comment.id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询错误")

    if action=="add":
        if not comment_like_query:
            new_comment_like = CommentLike()
            new_comment_like.user_id = user.id
            new_comment_like.comment_id = comment.id
            try:
                db.session.add(new_comment_like)
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)
                db.session.rollback()
                return jsonify(errno=RET.DBERR, errmsg="数据存储错误")
    else:
        if comment_like_query:
            try:
                db.session.delete(comment_like_query)
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)
                db.session.rollback()
                return jsonify(errno=RET.DBERR, errmsg="数据库删除错误")

    # 4. 返回数据
    return jsonify(errno=RET.OK, errmsg="操作成功")